package com.iflytek.sbd.demo.lambda.lambdacanshu;


import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;

/**
 * @program: sbd
 * @description: 函数式接口作为参数
 * @author: 陈英俊
 * @create: 2022-01-06 09:55
 */
public class Demo {


    public static void main(String[] args) {
        /**
         * 观察consumer1和consumer2发现函数式接口对象,其实操作的都是函数式接口的匿名实现对象
         * lambda的第一段其实是匿名实现子类的参数,第二段是匿名实现子类的方法体
         */
        Consumer<Set<String>> consumer1 = new Consumer<Set<String>>() {
            @Override
            public void accept(Set<String> set) {
                set.remove("123");
            }
        };
        Consumer<Set<String>> consumer2 = set -> set.remove("123");

        updateManualSingletonNames(set -> set.remove("123"), set -> set.contains("123"));
    }

    /**
     * 使用函数式接口作为参数,其实传递过来的都是函数式接口的匿名实现子类对象,经过lambda省略之后传输过来的就是 x->y
     *
     * @param action    函数式接口匿名实现子类对象, 这个封装动作
     * @param condition 函数式接口匿名实现子类对象,这个封装断言
     *                  根据不同的断言,执行动作
     */
    public static void updateManualSingletonNames(Consumer<Set<String>> action, Predicate<Set<String>> condition) {
        /**
         *经过参数传递参数为:
         * Consumer<Set<String>> action　= set -> set.remove("123") ,Predicate<Set<String>> condition = set -> set.contains("123")
         * 上面已经讲过 第一段是匿名实现子类的方法参数,第二段匿名实现子类的方法体 , 其实就会发现还缺少一个方法参数, 如何传输这个参数呢?
         * 我们可以直接拿接口调用方法传入参数,这样实际调用的是子类匿名对象,它也顺利拿到了参数
         */
        //根据不同的断言,执行动作, 处理的对象可以不一致
        Set<String> set = new HashSet<>();
        set.add("123");
        System.out.println(set);
        if (condition.test(set)) {
            action.accept(set);
        }
        System.out.println(set);
    }
}
